<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ChromeGestures</title>
<!--<link href="chrome-native-look.css" rel="stylesheet" type="text/css" />-->
<script type="text/javascript" src="x.js"></script>
<script type="text/javascript" src="tween2.js"></script>
<script type="text/javascript" src="chrome_gestures.user.js"></script>
<link href="option_page.css" rel="stylesheet" type="text/css">
<body>
<ul class="tabs" id="menu_tabs">
	<li class="basics"><a href="#basics" class="active"><span>Basics</span></a>
	<li class="actions"><a href="#actions"><span>Actions</span></a>
	<li class="drag-actions"><a href="#drag-actions"><span>Drag Actions</span></a>
	<li class="advanced"><a href="#advanced"><span>Advanced</span></a>
	<li class="news"><a href="#news"><span>News</span></a>
	<li class="about"><a href="#about"><span>About</span></a>
</ul>
<div id="container">
<div id="inner_container">
<section id="basics" class="content">
	<div><input type="checkbox" id="mouse_track"><label for="mouse_track">Mouse Track</label></div>
	<div class="sub"><input type="checkbox" id="visualized_arrow"><label for="visualized_arrow">Visualize Arrow</label></div>
	<div><input type="checkbox" id="superdrag"><label for="superdrag">Super Drag(Drag&amp;Drop Action)</label></div>
	<div><input type="checkbox" id="suppress_contextmenu"><label for="suppress_contextmenu">Suppress contextmenu, when gesture failed</label></div>
	<div>
		<label for="minimumUnit">Minimum Unit</label>
		<div class="ranges">
			<span class="mins">0</span>
			<input type="range" id="minimumUnit" max="50" min="1" step="1" placeholder="10">
			<span class="maxs">50</span>
		</div>
		<span class="outputs" id="minimumUnit_value"></span>
		<button>reset</button>
	</div>
	<div><input type="checkbox" id="useMousewheel"><label for="useMousewheel">use Mouse Wheel</label></div>
	<div class="sub Mousewheel"><input type="checkbox" id="useTabList"><label for="useTabList">Tabs List(Rigth click &amp; Mouse Wheel. Note:webpage can read your lists.)</label></div>
	<div class="sub Mousewheel"><input type="checkbox" id="useSmoothScroll"><label for="useSmoothScroll">use Smooth Scroll</label></div>
	<div class="sub Mousewheel">
		<label for="ScrollSpeedValue">Speed</label>
		<div class="ranges">
			<span class="mins">0.1</span>
			<input type="range" id="ScrollSpeedValue" max="10" min="1" step="1" placeholder="2">
			<span class="maxs">1</span>
		</div>
		<span class="outputs" id="ScrollSpeedValue_value"></span>
		<button>reset</button>
	</div>
	<div class="sub Mousewheel">
		<input type="checkbox" id="useScrollAcceleration"><label for="useScrollAcceleration">Scroll Acceleration</label>
	</div>
	<div class="sub Mousewheel">
		<label for="AccelerationValue">Acceleration Value</label>
		<div class="ranges">
			<span class="mins">1</span>
			<input type="range" id="AccelerationValue" max="20" min="1" step="1" placeholder="5">
			<span class="maxs">20</span>
		</div>
		<span class="outputs" id="AccelerationValue_value"></span>
		<button>reset</button>
	</div>
</section>
<section id="actions" class="content">
	<div class="box">
		<div class="field_action">
			<button id="normal_append_action">add new gesture</button>
		</div>
		<dl id="normal_action_list">
		</dl>
	</div>
</section>
<section id="drag-actions" class="content">
	<div class="box">
		<h3>for link</h3>
		<div class="field_action">
			<button id="linkdrag_append_action">add new gesture</button>
		</div>
		<dl id="linkdrag_action_list">
		</dl>
	</div>
	<div class="box">
		<h3>for text</h3>
		<div class="field_action">
			<button id="textdrag_append_action">add new gesture</button>
		</div>
		<dl id="textdrag_action_list">
		</dl>
	</div>
</section>
<section id="advanced" class="content">
	<textarea id="config_text"></textarea>
	<div><button id="export_conf">Export Configuration</button></div>
	<div><button id="import_conf">Import Configuration</button></div>
	<div class="margin">
		<button id="reset_all">Reset All Configuration</button>( Please backup current configuration. )
	</div>
</section>
<section id="news" class="content">
	<ul>
	<li>
	<h4>2010/02/11 21:48</h4>
	<p>ページの何もないところでジェスチャーできないケースがあった問題を修正。</p>
	<p>1画面スクロールを追加。</p>
	</li>
	<li>
	<h4>2010/01/26 21:05</h4>
	<p>「ページの読み込み途中でも動作するように修正した」副作用で画像だけを表示した状態のときにジェスチャーが動かなくなっていたので修正。</p>
	</li>
	<li>
	<h4>2010/01/21 23:31</h4>
	<p>ページの読み込み途中でも動作するように修正しました。</p>
	<p>ローカライズをChrome本体の言語設定に従うようにしました。</p>
	<p>閲覧履歴の削除などでローカルストレージが消えた際に、設定を保存し直すようにしました。</p>
	</li>
	<li>
	<h4>2009/12/31 5:47</h4>
	<p>ドラッグ時のアクションを設定できるようにしました。</p>
	</li>
	<li>
	<h4>2009/12/30 2:34</h4>
	<p>ページのURLやタイトルをクリップボードにコピーするアクションを追加しました。</p>
	</li>
	<li>
	<h4>2009/12/14 12:27</h4>
	<p>バックアップした設定をインポートできなかった問題を修正。</p>
	</li>
	<li>
	<h4>2009/12/12 15:27</h4>
	<p>再起動するとローカライズ出来ていなかった問題を修正しました。</p>
	<p>新しいアクションの追加方法を改善しました。</p>
	<p>矢印を可視化するオプションを追加しました。マッチしたアクション名も表示されます。</p>
	<p>新規タブや拡張ギャラリーで動かないのは(今のところ)Chromeの仕様です。将来的には改善されると思います。</p>
	</li>
	<li>
	<h4>2009/12/06 2:47</h4>
	<p>GuesturesをGesturesに修正。「指定のURLに移動する」、「指定のURLを新規タブで開く」、「スクリプトを実行」などのアクションを追加。Thx! <a href="http://bitbucket.org/gimite/" target="_blank">gimite</a></p>
	<p>簡易版のスーパードラッグ追加(リンクをドラッグすると新規タブで開く)</p>
	<p>設定のインポート・エキスポート追加</p>
	<p>Optionsページが表示できていなかった問題を修正。Thx! <a href="http://twitter.com/r_of_p/status/6373273377" target="_blank">@r_of_p</a></p>
	<p>一応国際化(日本語とアレな英語だけだけど…)。このNewsは言語設定で日本語を選んでないと出ないようになっています。</p>
	</li>
	<li>
	<h4>2009/11/19 11:34</h4>
	<p>Chromiumでfileスキームを指定できなくなるので緊急対応。設定ページの見た目を弄ってますが、まだ暫定版です。</p>
	</li>
	<li>
	<h4>2009/10/22 15:40</h4>
	<p>スクロール監視をした状態でスムーズスクロールを無効にした場合、ページによってはスクロールできなくなるバグを修正。Thx <a href="http://twitter.com/MJ_twelve/status/5059674711" target="_blank">@MJ_twelve</a></p>
	</li>
	<li>
	<h4>2009/10/11 3:12</h4>
	<p>スムーズスクロールと加速スクロールを実装しました。</p>
	<p>スムーススクロールでは、スクロール時間を0.1秒から1秒の間で指定できます。</p>
	<p>加速スクロールを有効にすると、マウスホイールを素早く動かした場合に、その速度に応じてスクロール量を増やすことができます。</p>
	<p>特にスムーススクロールはページによっては正常に動かないかもしれません。そういったページを見つけた場合は下記からURL付きでバグ報告を頂けると助かります。</p>
	</li>
	<li>
	<h4>2009/10/xx</h4>
	<p>バグ報告、ご要望などは<a href="http://bitbucket.org/os0x/chromegestures/issues/" target="_blank">bitbucket</a>に頂けると助かります。OpenIDに対応していますので、はてな、Yahoo、mixiなどのアカウントでログインできます。</p>
	</li>
	</ul>
</section>
<section id="about" class="content">
	<dl>
		<dt>Name:<dt>
		<dd><a href="https://chrome.google.com/extensions/detail/jpkfjicglakibpenojifdiepckckakgk" target="_blank">Chrome Gestures</a></dd>
		<dt>Version:<dt>
		<dd>ver <span id="ExtensionVersion"></span></dd>
		<dt>Author:<dt>
		<dd><a href="http://ss-o.net/" target="_blank">os0x</a></dd>
		<dt>License:<dt>
		<dd><a href="http://creativecommons.org/licenses/MIT/" target="_blank">The MIT license</a></dd>
		<dt>Thanks:<dt>
		<dd><a href="http://gimite.net/" target="_blank">Gimite</a></dd>
		<dd><a href="http://www.xuldev.org/misc/script/MouseGestures.uc.js" target="_blank">Gomita</a>, <a href="http://github.com/ArcCosine/userscript/raw/master/simple_guestures.user.js#" target="_blank">Arc Cosine</a></dd>
	</dl>
</section>
</div>
</div>
<div id="cover"><!--
<h3>Please do mouse action</h3>
<div id="action_result"></div>
<button id="ok">OK</button>
<button id="cancel">cancel</button>
-->
</div>
<script>
window.onload = function(){
	setTimeout(__onload, 100);
};
function __onload(){
document.addEventListener('click',function(evt){
	var target = evt.target;
	if (target instanceof HTMLAnchorElement && target.href && target.href.indexOf('http') === 0) {
		evt.preventDefault();
		chrome.tabs.create({url:target.href});
	}
},false);
BackGround = chrome.extension.getBackgroundPage();
//_ = BackGround._;
GesturesInfo = BackGround.GesturesInfo;
MG = BackGround.MG;
if (this.ChromeGesture) {
	ChromeGesture.mouse_track = true;
	ChromeGesture.visualized_arrow = true;
	ChromeGesture.normal_actions = GesturesInfo.normal_actions;
	ChromeGesture.linkdrag_actions = GesturesInfo.linkdrag_actions;
	ChromeGesture.textdrag_actions = GesturesInfo.textdrag_actions;
	ChromeGesture.config = GesturesInfo;
}
function L10N(){
	chrome.i18n.getAcceptLanguages(function(langs){
		if (langs.indexOf('ja') < 0 ) {
			document.querySelector('#menu_tabs > li.news').style.display = 'none';
		}
	});
	var labels = document.querySelectorAll('label')
	for (var i = 0; i < labels.length; i++){
		var message = chrome.i18n.getMessage('options_' + labels[i].htmlFor);
		if (message) {
			labels[i].innerHTML = message;
		}
	}
}
L10N();

var WIDTH = 800;
var HEIGHT = Math.max(window.innerHeight - 100, 500);
var cover = document.getElementById('cover');
cover.addEventListener('click', function(evt){
	if (evt.target === cover) {
		cover_close();
	}
},false);
var _performAction = ChromeGesture._performAction;
var superdrag_action = ChromeGesture.superdrag_action;
function cover_close(callback){
	cover.style.display = 'none';
	while (cover.firstChild) cover.removeChild(cover.firstChild);
	ChromeGesture._performAction = _performAction;
	ChromeGesture.superdrag_action = superdrag_action;
}

var GP = {
	"U":"↑",
	"D":"↓",
	"L":"←",
	"R":"→"
};
var ARROW_ICON = {
	U:'up.png',
	R:'right.png',
	D:'down.png',
	L:'left.png'
};
var PG = {
	"↑":"U",
	"↓":"D",
	"←":"L",
	"→":"R"
}

$X('/html/body/div/div/section/div/input[@type="checkbox"]').forEach(function(box){
	var id = box.id;
	var val = GesturesInfo[id];
	if (val === true || val === false) {
		box.checked = val;
	} else {
		//return;
	}
	box.addEventListener('click',function(){
		if (box.checked) {
			GesturesInfo[id] = true;
		} else {
			GesturesInfo[id] = false;
		}
		MG.update();
	},false);
});
$X('/html/body/div/div/section/div/div/input[@type="range"]').forEach(function(box){
	var id = box.id;
	var output = document.querySelector('#' + id + '_value');
	var val = GesturesInfo[id];
	if (id === 'ScrollSpeedValue'){
		box.value = val*10;
		output.textContent = String(val);
		update = updateFix;
	} else {
		box.value = val;
		output.textContent = box.value;
	}
	box.addEventListener('change',update,false);
	function update(){
		GesturesInfo[id] = +this.value;
		output.textContent = box.value;
		MG.update();
	}
	function updateFix(){
		GesturesInfo[id] = this.value/10;
		output.textContent = box.value/10;
		MG.update();
	}
	var reset = box.parentNode.parentNode.querySelector('button');
	if (reset){
		reset.addEventListener('click',function(){
			box.value = box.placeholder;
			update.call(box);
		},false);
	}
});

var useMousewheel = document.getElementById('useMousewheel');
useMousewheel.addEventListener('click', toggleMouseSettings,false);
function toggleMouseSettings(){
	$X('id("basics")/div[contains(@class,"Mousewheel")]//input').forEach(function(input){
		input.disabled = !useMousewheel.checked;
	});
}
if (!useMousewheel.checked) {
	toggleMouseSettings();
}

var drag_actions = document.getElementById('drag-actions');
var dragtab = $X('id("menu_tabs")/li[@class="drag-actions"]')[0];
document.getElementById('superdrag').addEventListener('click',toggle_drag_conf,false);
function toggle_drag_conf(e){
	if (e.target.checked) {
		drag_actions.style.visibility = 'visible';
		dragtab.style.display = 'inline-block';
	} else {
		drag_actions.style.visibility = 'hidden';
		dragtab.style.display = 'none';
	}
}
toggle_drag_conf({target:document.getElementById('superdrag')});

document.getElementById('ExtensionVersion').textContent = BackGround.Manifest.version;

var ActionConfig = function(prefix, ActionNames){
	var action_list = document.getElementById(prefix + 'action_list');
	var append_action = document.getElementById(prefix + 'append_action');
	//var action_text = document.getElementById(prefix + 'action_text');
	var actions = GesturesInfo[prefix + 'actions'];
	var ActionKeys = [];
	for (var k in actions) ActionKeys.push(k);
	var Actions = ActionKeys.sort().map(function(k){
		var act=actions[k];
		return {key:k,name:act.name,args:act.args};
	}).map(create_action);
	function create_action(act, i) {
		var dt = document.createElement('dt');
		var dd = document.createElement('dd');
		dt.innerHTML = '<span class="lt">Gesture:</span>';
		var key = document.createElement('span');
		key.className = 'key';
		//key.textContent = act.key.split('').map(function(s){
		act.key.split('').forEach(function(s){
			var img = document.createElement('img');
			img.src = ARROW_ICON[s];
			key.appendChild(img);
		});
		dt.appendChild(key);
		var action = document.createElement('select');
		var args_list;
		MG[ActionNames].forEach(function(group){
			var optg = document.createElement('optgroup');
			optg.setAttribute('label', group.label || group.group);
			group.actions.forEach(function(_act, i){
				var opt = document.createElement('option');
				opt.value = group.group + '::' + _act.name;
				opt.textContent = (group.labels && group.labels[i]) || _act.name;
				if (_act.name === act.name) {
					if (_act.args.length) {
						set_arg(_act);
					}
					opt.selected = true;
				}
				optg.appendChild(opt);
			});
			action.appendChild(optg);
		});
		function set_arg(_act){
			args_list = document.createElement('ul');
			var args = [];
			_act.args.forEach(function(_arg, i){
				var _i = i+1;//, KEY = act.key;
				var _li = document.createElement('li');
				_li.innerHTML = '<span class="lt">' + _arg.type + ':</span>';
				var arg;
				if (_arg.type === 'custom tag') {
					arg = document.createElement('textarea');
				} else if (_arg.type === 'hidden') {
					arg = document.createElement('input');
					arg.type = 'hidden';
				} else {
					arg = document.createElement('input');
					arg.type = 'text';
					if (_arg.type === 'KEY') {
						arg.maxLength = 1;
					}
				}
				if (act.args[i] !== void 0) {
					arg.value = act.args[i];
				} else if (_arg.default_value !== void 0) {
					arg.value = _arg.default_value;
				}
				arg.addEventListener('change',function(){
					args[i] = arg.value;
					MG.arg_set(act.key, {name:_act.name, args:args}, prefix);
				},false);
				arg.setAttribute('placeholder', _arg.type);
				_li.appendChild(arg);
				args_list.appendChild(_li);
				args.push(arg.value || '');
			});
			dd.insertBefore(args_list, dd.firstChild);
			return args;
		}
		function del_arg(){
			if (args_list) {
				dd.removeChild(args_list);
				args_list = null;
			}
		}
		action.addEventListener('change',function(e){
			del_arg();
			var _act = MG[ActionNames+'_hash'][action.value], args;
			if (_act.args.length) {
				args = set_arg(_act);
			}
			act.name = action.value;
			act.label = chrome.i18n.getMessage('action_name_' + act.name.replace(/\W/g,'_'));
			MG.set(act.key, _act.name, prefix, args);
		},false);
		var span = document.createElement('span');
		span.className = 'lt';
		span.textContent = 'Action:';
		dd.appendChild(span);
		dd.appendChild(action);
		if (act.key.indexOf('#') !== 0) {
			var del = document.createElement('button');
			del.textContent = 'Del';
			del.addEventListener('click',function(){
				action.disabled = !action.disabled;
				if (action.disabled) {
					MG.del(act.key, prefix);
					del.textContent = 'Undo';
					dt.className = 'disabled';
					dd.className = 'disabled';
				} else {
					MG.set(act.key, action.value, prefix);
					del.textContent = 'Del';
					dt.className = '';
					dd.className = '';
				}
			});
			dd.appendChild(del);
		} else {
			key.textContent = act.key.slice(1);
		}
		action_list.insertBefore(dt, act.point);
		action_list.insertBefore(dd, act.point);
		act.list = dt;
		act.dlist = dd;
		if (act.focus) {
			action.focus();
		}
		return act;
	}
	append_action.addEventListener('click',function(){
		cover.style.height = document.documentElement.clientHeight + 'px';
		cover.style.width = document.documentElement.clientWidth + 'px';
		cover.style.display = 'block';
		var h3 = document.createElement('h3');
		h3.textContent = 'Please do mouse action';
		cover.appendChild(h3);
		var action_result = document.createElement('div');
		action_result.id = 'action_result';
		cover.appendChild(action_result);
		var ok = document.createElement('button');
		ok.textContent = 'ok';
		ok.disabled = true;
		var cancel = document.createElement('button');
		cancel.textContent = 'cancel';
		cover.appendChild(ok);
		cover.appendChild(cancel);
		cancel.addEventListener('click',cover_close,false);
		var ActionResult = '';
		ok.addEventListener('click',function(evt){
			cover_close();
			if (ActionResult) {
				actionInit(ActionResult);
			}
		});
		var dummy = document.createElement('div');
		dummy.setAttribute('style','margin:3em 0;');
		cover.appendChild(dummy);
		if (ActionNames.indexOf('linkdrag') === 0) {
			var a = document.createElement('a');
			a.href="options_page.html";
			a.textContent = 'drag this link';
			dummy.appendChild(a);
		}
		if (ActionNames.indexOf('textdrag') === 0) {
			var span = document.createElement('span');
			span.textContent = 'drag this text';
			dummy.appendChild(span);
			getSelection().selectAllChildren(span);
		}
		ChromeGesture.superdrag_action = ChromeGesture._performAction = function(){
			ActionResult = this._directionChain || '';
			action_result.innerHTML = '';
			ActionResult.split('').forEach(function(s){
				var img = document.createElement('img');
				img.src = ARROW_ICON[s];
				action_result.appendChild(img);
			});
			if (ActionResult) {
				ok.disabled = false;
			} else {
				ok.disabled = true;
			}
		};
	});
	var actionInit = function(key){
		if (!key || /[^UDLR]/i.test(key)) {
			return;
		}
		if (ActionKeys.indexOf(key) !== -1) {
			var i = ActionKeys.indexOf(key);
			var s = Actions[i].dlist.getElementsByTagName('select')[0];
			if (s) s.focus();
			return;
		}
		ActionKeys.push(key);
		ActionKeys.sort();
		var index = ActionKeys.indexOf(key);
		var point = (Actions[index] || {}).list;
		var act = {key:key,focus:true,point:point,name:'no action',args:[]};
		Actions = Actions.slice(0, index).concat([act], Actions.slice(index));
		create_action(act, index);
		MG.set(act.key, act.name, prefix);
		//action_text.value ='';
	};
};

ActionConfig('normal_', 'action_names');
ActionConfig('linkdrag_', 'linkdrag_action_names');
ActionConfig('textdrag_', 'textdrag_action_names');

var config_text = document.getElementById('config_text');
var export_conf = document.getElementById('export_conf');
export_conf.addEventListener('click',function(){
	config_text.value = JSON.stringify(GesturesInfo, null, 2);
},false);
var import_conf = document.getElementById('import_conf');
import_conf.addEventListener('click',function(){
	if (!config_text.value){
		return;
	}
	try {
		JSON.parse(config_text.value);
	} catch (e) {
		alert('インポートに失敗しました。正しいJSONではありません。');
		return;
	}
	var conf = JSON.parse(config_text.value);
	var _config = GesturesInfo;
	try {
		if (conf.version !== BackGround.Manifest.version) {
			if (!confirm('設定がExportされた際のバージョンと現在の使用しているバージョンが異なるため、正常にインポートできない可能性があります。現在の設定をバックアップしてから続行することを推奨します。\n続行しますか?')){
				return;
			}
		}
		GesturesInfo = conf;
		BackGround.GesturesInfo = GesturesInfo;
		MG.update();
	} catch (e) {
		alert('インポートに失敗しました。');
		BackGround.GesturesInfo = _config;
		MG.update();
		return;
	}
	alert('正常にインポートできました。新しい設定を再読み込みします。');
	location.reload();
},false);
var reset_all = document.getElementById('reset_all');
reset_all.addEventListener('click',function(){
	if (confirm('Are sure you want to delete this config? There is NO undo!')) {
		GesturesInfo = BackGround.defaultGesturesInfo;
		BackGround.GesturesInfo = GesturesInfo;
		MG.update();
		location.reload();
	}
},false);


var sections = $X('/html/body/div/div/section[contains(@class, "content")]');
var inner_container = document.getElementById('inner_container');
var container = document.getElementById('container');
inner_container.style.width = sections.length * (WIDTH+20) + 'px';
//inner_container.style.height = HEIGHT + 'px';
//container.style.height = HEIGHT + 'px';
container.style.marginTop = '-2px';
sections.forEach(function(section, _i){
	section.style.visibility = 'hidden';
	section.style.height = '100px';
});
var btns = $X('id("menu_tabs")/li/a');
var default_title = document.title;
btns.forEach(function(btn, i, btns){
	btn.addEventListener('click',function(evt){
		evt.preventDefault();
		btns.forEach(function(btn){btn.className = '';})
		btn.className = 'active';
		sections[i].style.visibility = 'visible';
		sections[i].style.height = 'auto';
		new Tween(inner_container.style, {marginLeft:{to:i * -WIDTH,tmpl:'$#px'},time:0.2,onComplete:function(){
				document.title = default_title + btn.hash;
				location.hash = btn.hash;
				window.scrollBy(0, -1000);
				sections.forEach(function(section, _i){
					if (i !== _i) {
						section.style.visibility = 'hidden';
						section.style.height = '100px';
					}
				});
			}});
	}, false);
});
if (location.hash) {
	sections.some(function(section, i){
		if ('#' + section.id === location.hash) {
			btns.forEach(function(btn){btn.className = '';})
			btns[i].className = 'active';
			inner_container.style.marginLeft = -WIDTH * i + 'px';
			section.style.visibility = 'visible';
			section.style.height = 'auto';
			document.title = default_title + location.hash;
		}
	});
} else {
	sections[0].style.height = 'auto';
	sections[0].style.visibility = 'visible';
	document.title = default_title + '#' + sections[0].id;
}
};
</script>
</body>
</html>
